package org.iabako.client.ui.form.business.service;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.HTMLPanel;
import org.iabako.client.config.page.PageConfigEnum;
import org.iabako.client.navigation.NavigationController;
import org.iabako.client.tools.IabakoAsyncCallback;
import org.iabako.client.tools.Messages;
import org.iabako.client.ui.form.AbstractForm;
import org.iabako.client.ui.layout.field.*;
import org.iabako.client.ui.layout.template.Popup;
import org.iabako.client.ui.layout.widget.validation.ValidationMessage;
import org.iabako.client.ui.page.business.service.ServiceCreate;
import org.iabako.client.ui.page.business.service.ServiceSearch;
import org.iabako.client.user.AuthenticateUserProvider;
import org.iabako.shared.entity.business.AbstractEntity;
import org.iabako.shared.entity.business.Service;
import org.iabako.shared.entity.enumeration.InstallmentsType;
import org.iabako.shared.entity.enumeration.TrackingType;
import org.iabako.shared.iservice.business.ServiceServiceAsync;
import org.iabako.shared.tools.GenericTools;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by jose on 15/02/14.
 */
public abstract class ServiceForm extends AbstractForm {

    interface MyUiBinder extends UiBinder<HTMLPanel, ServiceForm> {
    }

    protected MyUiBinder binderForm = GWT.create(MyUiBinder.class);

    protected final ServiceServiceAsync serviceServiceAsync = ServiceServiceAsync.Util.getInstance();

    @UiField
    InputText number;
    @UiField
    InputText name;
    @UiField
    InputTextArea description;
    @UiField
    InputTextAmount servicePrice;
    @UiField
    RadioButtonList installmentsType;
    @UiField
    InputSwitch taxIncluded;
    @UiField
    HTMLPanel taxInput;
    @UiField
    InputTextAmount taxPercent;

    protected ServiceForm(PageConfigEnum pageConfigEnum, String explanationMenuLabel) {

        setForm(binderForm, pageConfigEnum, explanationMenuLabel);

        Popup.resizeToSmallPopup();

        setDefaultValues();

        setHandlers();
    }

    private void setHandlers() {
        taxIncluded.addValueChangeHandler(new ValueChangeHandler() {
            public void onValueChange(ValueChangeEvent valueChangeEvent) {
                taxInput.setVisible(taxIncluded.getValue());
                servicePrice.setInputTitle(Messages.getLabel(taxIncluded.getValue() ? "service_form_price_with_tax" : "service_form_price"));
            }
        });
    }

    private void setDefaultValues() {
        if (this instanceof ServiceCreate) {
            serviceServiceAsync.getNextAvailableId(new IabakoAsyncCallback<String>() {
                public void onSuccess(String result) {
                    number.setValue(result);
                    super.onSuccess(result);
                }
            });
        }
        serviceServiceAsync.getLastTax(new IabakoAsyncCallback<Double>() {
            public void onSuccess(Double tax) {
                if (taxPercent.getAmountValue() == null && tax != null) {
                    taxPercent.setValue(GenericTools.formatAmount(tax + ""));
                }
                super.onSuccess(tax);
            }
        });
    }

    @Override
    protected AbstractEntity getEntity() {
        if (entity == null) {
            entity = new Service();
        }
        Service service = (Service) entity;
        service.setNumber(number.getValue());
        service.setName(name.getValue());
        service.setDescription(description.getValue());
        service.setInstallmentType((InstallmentsType) installmentsType.getValue());

        service.setPrice(servicePrice.getAmountValue());

        if (taxIncluded.getValue()) {
            service.setTaxPercent(taxPercent.getAmountValue());
        } else {
            service.setTaxPercent(null);
        }

        return service;
    }

    @Override
    protected List<IField> getMandatoryFields() {
        List<IField> mandatoryFields = new ArrayList<IField>();
        mandatoryFields.add(number);
        mandatoryFields.add(name);
        mandatoryFields.add(description);
        mandatoryFields.add(installmentsType);
        mandatoryFields.add(servicePrice);
        mandatoryFields.add(taxIncluded);

        if (taxIncluded.getValue()) {
            mandatoryFields.add(taxPercent);
        }

        return mandatoryFields;
    }


    @Override
    public boolean validate() {
        if (!uiValidation()) {
            return false;
        }
        Service service = (Service) serverValidation();
        if (service == null) {
            return false;
        }

        final boolean creation = service.getId() == null;

        serviceServiceAsync.save(service, new IabakoAsyncCallback<Service>() {
            public void onSuccess(Service result) {
                popup.handleClickClose();

                ValidationMessage validationMessageInPageContent = ValidationMessage.getFromRootPage();
                if (creation) {
                    validationMessageInPageContent.showSuccessMessage("validation_service_form_create_success");
                    AuthenticateUserProvider.getTrackingPanel().refresh(TrackingType.serviceNew);
                } else {
                    validationMessageInPageContent.showSuccessMessage("validation_service_form_modify_success");
                    AuthenticateUserProvider.getTrackingPanel().refresh(TrackingType.serviceModify);
                }

                if (NavigationController.getInstance().getRootPage().pageContentComposite instanceof ServiceSearch) {
                    //If rootPage is ServiceSearch, we have to refresh search
                    ((ServiceSearch) NavigationController.getInstance().
                            getRootPage().pageContentComposite).serviceSearchForm.searchForm.search(false);
                }

                super.onSuccess(result);
            }
        });
        return true;
    }

    protected void setService(Service service) {

        entity = service;

        number.setValue(service.getNumber());
        name.setValue(service.getName());
        description.setValue(service.getDescription());
        installmentsType.setValue(service.getInstallmentType());
        servicePrice.setValue(GenericTools.formatAmount(service.getPrice() + ""));

        if (service.getTaxPercent() != null) {
            taxIncluded.setValue(true);
            taxPercent.setValue(GenericTools.formatAmount(service.getTaxPercent() + ""));
        } else {
            taxIncluded.setValue(false);
        }

        enableAddLinkAction(serviceServiceAsync);
    }

}
